package com.ia2014.tp.portal2.entities;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.log4j.Logger;

import com.ia2014.tp.portal2.converter.ConvVO;
import com.ia2014.tp.portal2.enums.EstadoVentaEnum;
import com.ia2014.tp.portal2.vo.VentaVO;

@Entity
@Table(name="Ventas")
public class Venta extends AbstractEntity<VentaVO>{

	@Transient
	private static Logger logger = Logger.getLogger(Venta.class);
	
	private Integer nroVenta;
	private Date fecha;
	private String estado;
	private Usuario usuario;
	private List<ItemVenta> items = new ArrayList<ItemVenta>();
	

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Integer getNroVenta() {
		return nroVenta;
	}
	
	public void setNroVenta(Integer nroVenta) {
		this.nroVenta = nroVenta;
	}
		
	@ManyToOne
	public Usuario getUsuario(){
		return this.usuario;
	}
	
	public void setUsuario(Usuario usuario){
		this.usuario = usuario;
	}
	
	public String getEstado(){
		return this.estado;
	}
	
	public void setEstado(String estado){
		this.estado = estado;
	}
	
	@OneToMany(mappedBy="venta", cascade=CascadeType.ALL)
	public List<ItemVenta> getItems(){
		return this.items;
	}
	
	public void setItems(List<ItemVenta> items){
		this.items = items;
	}
	
	public Date getFecha(){
		return this.fecha;
	}
	
	public void setFecha(Date fecha){
		this.fecha = fecha;
	}
	
	@Transient
	public Double calcularMontoTotal(){
		try{
			ItemVenta item = null;
		
			double total = 0;
		
			Iterator<ItemVenta> it = items.iterator();
		
			while (it.hasNext()) {
				item = it.next();
				total += item.calcularMonto();
			}
		
			return total;
		}
		catch (Exception e){
			if (this.usuario!=null)
				logger.error("Error al calcaualr el Monto Total de la Venta del Usuario " + this.usuario.getUserLogin());
			else
				logger.error("Error al calcaualr el Monto Total de la Venta");
			
			logger.error(e.toString());
			logger.debug("Stacktrace", e);
			return Double.valueOf(0);
		}
	}
	
	@Transient
	public void addItemVenta(ItemVenta item){
		this.items.add(item);
	}
	
	@Transient
	public void removeItemVenta(ItemVenta item){
		this.items.remove(item); 
	}
	
	
	@Transient
	public VentaVO getVOInstance(){
		return new VentaVO();
	}
	
	@Transient
	public VentaVO getVO(){
		try{
			VentaVO vo = new VentaVO();
		
			vo.setNroVenta(nroVenta);
			vo.setEstado(estado);
			vo.setFecha(fecha);
			vo.setUsuario(usuario.getVO());
		
			vo.setItems(ConvVO.getListaVoFromEntity(this.items));
		
			return vo;
		}
		catch (Exception e){
			
			logger.error("Error al tratrar de generar un Value Object de Venta");
			logger.error(e.toString());
			logger.debug("Stacktrace", e);
			return null;
		}	
	}
	
	@Transient
	public void setVO(VentaVO vo){
		try{
			if(this.nroVenta == null){
				this.setNroVenta(vo.getNroVenta());
			}
		
			this.setEstado(vo.getEstado());
			this.setFecha(vo.getFecha());
		
			if (vo.getUsuario()!= null){
				Usuario usuario = new Usuario();
				usuario.setUserLogin(vo.getUsuario().getUserLogin());
				this.setUsuario(usuario);
			}
		
			this.items = ConvVO.getListaEntityFromVo(vo.getItems());
		}
		catch (Exception e){
			
			logger.error("Error al tratrar de cargar una Venta a partir de un Value Object");
			logger.error(e.toString());
			logger.debug("Stacktrace", e);
		}
	}

	/*
	 * Utilizado por la clase ItemVenta en el metodo getVO
	 * para evitar loop
	 * */
	@Transient
	public VentaVO getVOSinItems(){
		try{
			VentaVO vo = new VentaVO();
		
			vo.setNroVenta(nroVenta);
			vo.setEstado(estado);
			vo.setFecha(fecha);
			vo.setUsuario(usuario.getVO());
		
			//vo.setItems(ConvVO.getListaVoFromEntity(this.items));
		
			return vo;
		}
		catch (Exception e){
			
			logger.error("Error al tratrar de generar un Value Object de Venta sin los Items");
			logger.error(e.toString());
			logger.debug("Stacktrace", e);
			return null;
		}
	}
	
	@Transient
	public void setEstadoItems(String estado){
		try{
			
			for (ItemVenta item : this.items){
			
				item.setEstado(estado);
			
			}
			
		}
		catch (Exception e){
			logger.error("Error al tratrar de asignar el Estado a todos los items de la venta");
			logger.error(e.toString());
			logger.debug("Stacktrace", e);
		}
	}
}
